package com.htpay.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.htpay.aspect.AutoLog;
import com.htpay.model.common.Constant;
import com.htpay.model.common.DictConstant;
import com.htpay.model.common.ResponseBean;
import com.htpay.model.entity.*;
import com.htpay.model.vo.MerchantWalletModel;
import com.htpay.model.vo.MerchantWithDrawMoneyModel;
import com.htpay.service.*;
import com.htpay.util.JwtUtil;
import com.htpay.util.MerchantUtil;
import com.htpay.util.ObjectConvertUtils;
import com.htpay.util.PasswordUtil;
import com.htpay.util.support.QueryGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/sys/income")
public class IncomeController {

    @Autowired
    private IMerchantService merchantService;

    @Autowired
    private IMerchantIncomeService merchantIncomeService;

    @Autowired
    private IMerchantSettlementService merchantSettlementService;

    @Autowired
    private IMerchantIncomeActService merchantIncomeActService;

    @Autowired
    private IMerchantWalletService merchantWalletService;

    @AutoLog(value = "收支明细表查询")
    @GetMapping(value = "/statistic")
    public ResponseBean queryIncomeList(MerchantIncomeInfo merchantIncomeInfo,
                                        @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                        @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                        HttpServletRequest req) {
        ResponseBean bean = new ResponseBean();
        Integer merchantId = MerchantUtil.getMerchantId(req);
        merchantIncomeInfo.setMerchantId(merchantId);

        QueryWrapper<MerchantIncomeInfo> queryWrapper = QueryGenerator.initQueryWrapper(merchantIncomeInfo, req.getParameterMap());
        Page<MerchantIncomeInfo> page = new Page<MerchantIncomeInfo>(pageNo, pageSize);

        IPage<MerchantIncomeInfo> pageList = merchantIncomeService.page(page, queryWrapper);
        log.info("=============== 收支明细表查询 ================");
        log.info("查询当前页：" + pageList.getCurrent());
        log.info("查询当前页数量：" + pageList.getSize());
        log.info("查询结果数量：" + pageList.getRecords().size());
        log.info("数据总数：" + pageList.getTotal());
        log.info("================== END =============");
        return bean.success("操作成功!", pageList);
    }

    @AutoLog(value = "结算记录表查询")
    @GetMapping(value = "/withdrawList")
    public ResponseBean queryWithdrawList(MerchantSettlementFlow merchantSettlementFlow,
                                          @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                          @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                          HttpServletRequest req) {
        ResponseBean bean = new ResponseBean();
        Integer merchantId = MerchantUtil.getMerchantId(req);
        merchantSettlementFlow.setMerchantId(merchantId);

        QueryWrapper<MerchantSettlementFlow> queryWrapper = QueryGenerator.initQueryWrapper(merchantSettlementFlow, req.getParameterMap());
        Page<MerchantSettlementFlow> page = new Page<MerchantSettlementFlow>(pageNo, pageSize);

        IPage<MerchantSettlementFlow> pageList = merchantSettlementService.page(page, queryWrapper);
        log.info("=============== 结算记录表查询 ================");
        log.info("查询当前页：" + pageList.getCurrent());
        log.info("查询当前页数量：" + pageList.getSize());
        log.info("查询结果数量：" + pageList.getRecords().size());
        log.info("数据总数：" + pageList.getTotal());
        log.info("================== END =============");
        return bean.success("操作成功!", pageList);
    }

    @AutoLog(value = "获取余额信息")
    @GetMapping(value = "/getWalletInfo")
    public ResponseBean getWalletInfo(HttpServletRequest req) {
        ResponseBean bean = new ResponseBean();
        String token = req.getHeader(Constant.X_ACCESS_TOKEN);
        String account = JwtUtil.getClaim(token, Constant.ACCOUNT);

        //获取当前用户
        Merchant merchant = merchantService.getUserByName(account);

        if (merchant == null) {
            return bean.error("无效用户信息~");
        }

        //获取商户收款账户list && 余额信息
        List<MerchantIncomeAct> merchantIncomeActList = merchantIncomeActService.queryIncomeActListByMerchantId(merchant.getMerchantId());
        MerchantWalletInfo merchantWalletInfo = merchantWalletService.getWalletInfoByMerchantId(merchant.getMerchantId());

        MerchantWalletModel merchantWalletModel = new MerchantWalletModel();
        merchantWalletModel.setFreezeMoney(merchantWalletInfo.getFreezeMoney());
        merchantWalletModel.setTotalMoney(merchantWalletInfo.getMoney());
        merchantWalletModel.setMerchantId(merchantWalletInfo.getMerchantId());
        merchantWalletModel.setMerchantActList(merchantIncomeActList);

        return bean.success("操作成功!", merchantWalletModel);
    }

    @AutoLog(value = "查询收款账户list")
    @GetMapping(value = "/getIncomeActList")
    public ResponseBean getIncomeActList(MerchantIncomeAct merchantIncomeAct,
                                         @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                         @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                         HttpServletRequest req) {
        ResponseBean bean = new ResponseBean();
        Integer merchantId = MerchantUtil.getMerchantId(req);
        merchantIncomeAct.setMerchantId(merchantId);

        QueryWrapper<MerchantIncomeAct> queryWrapper = QueryGenerator.initQueryWrapper(merchantIncomeAct, req.getParameterMap());
        Page<MerchantIncomeAct> page = new Page<MerchantIncomeAct>(pageNo, pageSize);

        IPage<MerchantIncomeAct> pageList = merchantIncomeActService.page(page, queryWrapper);
        log.info("=============== 收款账户表查询 ================");
        log.info("查询当前页：" + pageList.getCurrent());
        log.info("查询当前页数量：" + pageList.getSize());
        log.info("查询结果数量：" + pageList.getRecords().size());
        log.info("数据总数：" + pageList.getTotal());
        log.info("================== END =============");
        return bean.success("操作成功!", pageList);
    }


    @AutoLog(value = "新增商户收款账户")
    @PostMapping(value = "/addIncomeAct")
    public ResponseBean addIncomeAct(@RequestBody MerchantIncomeAct merchantIncomeAct, HttpServletRequest req) {
        ResponseBean bean = new ResponseBean();

        //获取收款账户
        String payeeAct = merchantIncomeAct.getPayeeAct();
        if (ObjectConvertUtils.isEmpty(payeeAct)) {
            return bean.error("收款账户不能为空");
        }

        //收款账户类型
        /// 1支付宝、2微信、3网银、4其他
        /// bank_id:保留编码001、002，分别代表支付宝和微信，银行编码从003开始
        String withdrawType = merchantIncomeAct.getWithdrawType();
        if (ObjectConvertUtils.isEmpty(withdrawType)) {
            return bean.error("收款账户类型不能为空");
        }

        //银行编码
        String bankId = merchantIncomeAct.getBankId();
        if (ObjectConvertUtils.isEmpty(bankId)) {
            return bean.error("收款账户银行编码不能为空");
        }

        String bankName = merchantIncomeAct.getBankName();
        if (ObjectConvertUtils.isEmpty(bankName)) {
            return bean.error("收款账户银行名称不能为空");
        }

        //收款账户姓名
        String payeeName = merchantIncomeAct.getPayeeName();
        if (ObjectConvertUtils.isEmpty(payeeName)) {
            return bean.error("收款账户姓名不能为空");
        }

        //判断是否合法性
        bean = checkPayeeAct(bean, merchantIncomeAct);
        if (bean.getCode().equals(Constant.BUSI_ERROR_COD)) return bean;

        //获取当前商户merchantId
        Integer merchantId = MerchantUtil.getMerchantId(req);
        String account = MerchantUtil.getAccountName(req);

        //默认添加为使用中
        merchantIncomeAct.setMerchantId(merchantId);
        merchantIncomeAct.setDelFlag(DictConstant.DEL_FLAG_0);
        merchantIncomeAct.setCreateBy(account);
        merchantIncomeAct.setCreateTime(new Date());

        //添加商户收款账户信息
        merchantIncomeActService.addMerchantIncomeAct(merchantIncomeAct);

        return bean.success("操作成功！");
    }

    /**
     * 校验收款账号是否唯一
     *
     * @return
     */
    @AutoLog(value = "校验收款账户唯一性")
    @RequestMapping(value = "/checkOnlyPayeeAct", method = RequestMethod.GET)
    public ResponseBean checkOnlyPayeeAct(MerchantIncomeAct merchantIncomeAct) {
        ResponseBean bean = new ResponseBean();
        bean = checkPayeeAct(bean, merchantIncomeAct);
        return bean;
    }

    /**
     * 校验下收款账户合法性
     *
     * @param bean
     * @param merchantIncomeAct
     * @return
     */
    private ResponseBean checkPayeeAct(ResponseBean bean, MerchantIncomeAct merchantIncomeAct) {
        try {
            MerchantIncomeAct act = merchantIncomeActService.getOne(new QueryWrapper<MerchantIncomeAct>(merchantIncomeAct));
            if (act != null) {
                log.info("==== merchant income act: [" + act.getPayeeAct() + "]收款账号已存在 ====");
                return bean.error("收款账号已存在");
            }

        } catch (Exception e) {
            return bean.error(e.getMessage());
        }

        return bean.success("该收款账号可用");
    }

    @AutoLog(value = "提交提现记录")
    @RequestMapping(value = "/addWithdrawMoney", method = RequestMethod.POST)
    public ResponseBean addWithdrawMoney(@RequestBody MerchantWithDrawMoneyModel model,
                                         MerchantSettlementFlow record,
                                         HttpServletRequest req) {
        ResponseBean bean = new ResponseBean();

        String payeeAct = model.getPayeeAct();
        if (ObjectConvertUtils.isEmpty(payeeAct)) {
            return bean.error("收款账户不能为空");
        }

        String withdrawType = model.getWithdrawType();
        if (ObjectConvertUtils.isEmpty(withdrawType)) {
            return bean.error("收款账户类型不能为空");
        }

        String withdrawMoney = model.getWithdrawMoney();
        if (ObjectConvertUtils.isEmpty(withdrawMoney)) {
            return bean.error("提现金额不能为空");
        }

        BigDecimal withMoney = new BigDecimal(withdrawMoney);
        int flag = withMoney.compareTo(DictConstant.LEAST_WITH_DRAW_MONEY);
        if (flag < 0) {
            log.info("==== 发起提现金额[" + withMoney.toString() + "]低于最低提现额度[" + DictConstant.LEAST_WITH_DRAW_MONEY + "] ====");
            return bean.error("提现金额不能低于最低额度: " + DictConstant.LEAST_WITH_DRAW_MONEY.toString());
        }

        String bankId = model.getBankId();
        if (ObjectConvertUtils.isEmpty(bankId)) {
            return bean.error("收款账户银行编码不能为空");
        }

        String bankName = model.getBankName();
        if (ObjectConvertUtils.isEmpty(bankName)) {
            return bean.error("收款账户银行名称不能为空");
        }

        String pwd = model.getWithdrawPassword();
        if (ObjectConvertUtils.isEmpty(pwd)) {
            return bean.error("提现密码不能为空");
        }

        try {
            Integer merchantId = MerchantUtil.getMerchantId(req);
            String account = MerchantUtil.getAccountName(req);
            MerchantWalletInfo walletInfo = merchantWalletService.getWalletInfoByMerchantId(merchantId);
            log.info("==== 获取商户ID[" + merchantId + "]的余额信息成功 ====");

            String salt = walletInfo.getWithdrawSalt();
            String withdrawPwd = walletInfo.getWithdrawPassword();
            //获取的提现密码
            String withdrawPwdEncode = PasswordUtil.encrypt(account, pwd, salt);
            log.info("==== 提现密码[" + withdrawPwdEncode + "] , 余额提现密码[" + withdrawPwd + "] ====");

            if (!withdrawPwdEncode.equals(withdrawPwd)) {
                return bean.error("提现密码不正确");
            }

            MerchantIncomeAct incomeAct = merchantIncomeActService.getIncomeActByPayeeAct(payeeAct);
            if (incomeAct == null) {
                log.info("==== 收款账户[" + payeeAct + "]未发现 ====");
                return bean.error("您还未绑定该：" + payeeAct + "收款账户");
            }
            String payeeName = incomeAct.getPayeeName();
            log.info("==== 获取收款账户[" + payeeAct + "], 收款人[" + payeeName + "]的信息成功 ====");

            record.setMerchantId(merchantId);
            record.setWithdrawType(withdrawType.charAt(0));
            record.setWithdrawMoneyWithStr(withdrawMoney);
            record.setPayeeName(payeeName);
            record.setBankId(bankId);
            record.setBankName(bankName);
            record.setPayeeAct(payeeAct);
            record.setWithdrawStatus(DictConstant.DICT_WITH_DRAW_STATUS_1);
            record.setCreateBy(account);
            record.setCreateTime(new Date());
            //添加记录
            merchantSettlementService.save(record);

            return bean.success("操作成功");
        } catch (Exception e) {
            return bean.error(e.getMessage());
        }
    }

}
